home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / ASTRNOMY / EPHEM421.ZIP / FORMATS.C < prev    next >
C/C++ Source or Header  |  1990-09-13  |  8KB  |  384 lines

  1. /* basic formating routines.
  2.  * all the screen oriented printing should go through here.
  3.  */
  4.  
  5. #include <stdio.h>
  6. #include <math.h>
  7. #ifdef VMS
  8. #include <stdlib.h>
  9. #endif
  10. #include "astro.h"
  11. #include "screen.h"
  12.  
  13. extern char *strcpy();
  14.  
  15. /* suppress screen io if this is true, but always flog stuff.
  16.  */
  17. static int f_scrnoff;
  18. f_on ()
  19. {
  20.     f_scrnoff = 0;
  21. }
  22. f_off ()
  23. {
  24.     f_scrnoff = 1;
  25. }
  26.  
  27. /* draw n blanks at the given cursor position.  */
  28. f_blanks (r, c, n)
  29. int r, c, n;
  30. {
  31.     if (f_scrnoff)
  32.         return;
  33.     c_pos (r, c);
  34.     while (--n >= 0)
  35.         putchar (' ');
  36. }
  37.  
  38. /* print the given value, v, in "sexadecimal" format at [r,c]
  39.  * ie, in the form A:m.P, where A is a digits wide, P is p digits.
  40.  * if p == 0, then no decimal point either.
  41.  */
  42. f_sexad (r, c, a, p, mod, v)
  43. int r, c;
  44. int a, p;    /* left space, min precision */
  45. int mod;    /* don't let whole portion get this big */
  46. double v;
  47. {
  48.     char astr[32], str[32];
  49.     long dec;
  50.     double frac;
  51.     int visneg;
  52.     double vsav = v;
  53.  
  54.     if (v >= 0.0)
  55.         visneg = 0;
  56.     else {
  57.         if (v <= -0.5/60.0*pow(10.0,-1.0*p)) {
  58.         v = -v;
  59.         visneg = 1;
  60.         } else {
  61.         /* don't show as negative if less than the precision showing */
  62.         v = 0.0;
  63.         visneg = 0;
  64.         }
  65.     }
  66.  
  67.     dec = v;
  68.     frac = (v - dec)*60.0;
  69.     (void) sprintf (str, "59.%.*s5", p, "999999999");
  70.     if (frac >= atof (str)) {
  71.         dec += 1;
  72.         frac = 0.0;
  73.     }
  74.     dec %= mod;
  75.     if (dec == 0 && visneg)
  76.         (void) strcpy (str, "-0");
  77.     else
  78.         (void) sprintf (str, "%ld", visneg ? -dec : dec);
  79.  
  80.     /* would just do this if Turbo-C 2.0 %?.0f" worked:
  81.      * sprintf (astr, "%*s:%0*.*f", a, str, p == 0 ? 2 : p+3, p, frac);
  82.      */
  83.     if (p == 0)
  84.         (void) sprintf (astr, "%*s:%02d", a, str, (int)(frac+0.5));
  85.     else
  86.         (void) sprintf (astr, "%*s:%0*.*f", a, str, p+3, p, frac);
  87.  
  88.     (void) flog_log (r, c, vsav, astr);
  89.  
  90.     f_string (r, c, astr);
  91. }
  92.  
  93. /* print the given value, t, in sexagesimal format at [r,c]
  94.  * ie, in the form T:mm:ss, where T is nd digits wide.
  95.  * N.B. we assume nd >= 2.
  96.  */
  97. f_sexag (r, c, nd, t)
  98. int r, c, nd;
  99. double t;
  100. {
  101.     char tstr[32];
  102.     int h, m, s;
  103.     int tisneg;
  104.     
  105.     dec_sex (t, &h, &m, &s, &tisneg);
  106.     if (h == 0 && tisneg)
  107.         (void) sprintf (tstr, "%*s-0:%02d:%02d", nd-2, "", m, s);
  108.     else
  109.         (void) sprintf (tstr, "%*d:%02d:%02d", nd, tisneg ? -h : h, m, s);
  110.  
  111.     (void) flog_log (r, c, t, tstr);
  112.     f_string (r, c, tstr);
  113. }
  114.  
  115. /* print angle ra, in radians, in ra hours as hh:mm.m at [r,c]
  116.  * N.B. we assume ra is >= 0.
  117.  */
  118. f_ra (r, c, ra)
  119. int r, c;
  120. double ra;
  121. {
  122.     f_sexad (r, c, 2, 1, 24, radhr(ra));
  123. }
  124.  
  125. /* print time, t, as hh:mm:ss */
  126. f_time (r, c, t)
  127. int r, c;
  128. double t;
  129. {
  130.     f_sexag (r, c, 2, t);
  131. }
  132.  
  133. /* print time, t, as +/-hh:mm:ss (don't show leading +) */
  134. f_signtime (r, c, t)
  135. int r, c;
  136. double t;
  137. {
  138.     f_sexag (r, c, 3, t);
  139. }
  140.  
  141. /* print time, t, as hh:mm */
  142. f_mtime (r, c, t)
  143. int r, c;
  144. double t;
  145. {
  146.     f_sexad (r, c, 2, 0, 24, t);
  147. }
  148.  
  149. /* print angle, a, in rads, as degress at [r,c] in form ddd:mm */
  150. f_angle(r, c, a)
  151. int r, c;
  152. double a;
  153. {
  154.     f_sexad (r, c, 3, 0, 360, raddeg(a));
  155. }
  156.  
  157. /* print angle, a, in rads, as degress at [r,c] in form dddd:mm:ss */
  158. f_gangle(r, c, a)
  159. int r, c;
  160. double a;
  161. {
  162.     f_sexag (r, c, 4, raddeg(a));
  163. }
  164.  
  165. /* print the given modified Julian date, jd, as the starting date at [r,c]
  166.  * in the form mm/dd/yyyy.
  167.  */
  168. f_date (r, c, jd)
  169. int r, c;
  170. double jd;
  171. {
  172.     char dstr[32];
  173.     int m, y;
  174.     double d, tmp;
  175.  
  176.     mjd_cal (jd, &m, &d, &y);
  177.     (void) sprintf (dstr, "%2d/%02d/%04d", m, (int)(d), y);
  178.  
  179.     /* shadow to the plot subsystem as years. */
  180.     mjd_year (jd, &tmp);
  181.     (void) flog_log (r, c, tmp, dstr);
  182.     f_string (r, c, dstr);
  183. }
  184.  
  185. /* print the given double as a rounded int, with the given format.
  186.  * this is used to plot full precision, but display far less.
  187.  * N.B. caller beware that we really do expect fmt to refer to an int, not
  188.  *   a long for example. also beware of range that implies.
  189.  */
  190. f_int (row, col, fmt, f)
  191. int row, col;
  192. char fmt[];
  193. double f;
  194. {
  195.     char str[80];
  196.     int i;
  197.  
  198.     i = (f < 0) ? (int)(f-0.5) : (int)(f+0.5);
  199.     (void) sprintf (str, fmt, i);
  200.  
  201.     (void) flog_log (row, col, f, str);
  202.     f_string (row, col, str);
  203. }
  204.  
  205. f_char (row, col, c)
  206. int row, col;
  207. char c;
  208. {
  209.     if (f_scrnoff)
  210.         return;
  211.     c_pos (row, col);
  212.     putchar (c);
  213. }
  214.  
  215. f_string (r, c, s)
  216. int r, c;
  217. char *s;
  218. {
  219.     if (f_scrnoff)
  220.         return;
  221.     c_pos (r, c);
  222.     (void) fputs (s, stdout);
  223. }
  224.  
  225. f_double (r, c, fmt, f)
  226. int r, c;
  227. char *fmt;
  228. double f;
  229. {
  230.     char str[80];
  231.     (void) sprintf (str, fmt, f);
  232.     (void) flog_log (r, c, f, str);
  233.     f_string (r, c, str);
  234. }
  235.  
  236. /* print prompt line */
  237. f_prompt (p)
  238. char *p;
  239. {
  240.     c_pos (R_PROMPT, C_PROMPT);
  241.     c_eol ();
  242.     c_pos (R_PROMPT, C_PROMPT);
  243.     (void) fputs (p, stdout);
  244. }
  245.  
  246. /* clear from [r,c] to end of line, if we are drawing now. */
  247. f_eol (r, c)
  248. int r, c;
  249. {
  250.     if (!f_scrnoff) {
  251.         c_pos (r, c);
  252.         c_eol();
  253.     }
  254. }
  255.  
  256. /* print a message and wait for op to hit any key */
  257. f_msg (m)
  258. char *m;
  259. {
  260.     f_prompt (m);
  261.     (void) read_char();
  262. }
  263.  
  264. /* crack a line of the form X?X?X into its components,
  265.  *   where X is an integer and ? can be any character except '0-9' or '-',
  266.  *   such as ':' or '/'.
  267.  * only change those fields that are specified:
  268.  *   eg:  ::10    only changes *s
  269.  *        10    only changes *d
  270.  *        10:0  changes *d and *m
  271.  * if see '-' anywhere, first non-zero component will be made negative.
  272.  */
  273. f_sscansex (bp, d, m, s)
  274. char *bp;
  275. int *d, *m, *s;
  276. {
  277.     char c;
  278.     int *p = d;
  279.     int *nonzp = 0;
  280.     int sawneg = 0;
  281.     int innum = 0;
  282.  
  283.     while (c = *bp++)
  284.         if (c >= '0' && c <= '9') {
  285.         if (!innum) {
  286.             *p = 0;
  287.             innum = 1;
  288.         }
  289.         *p = *p*10 + (c - '0');
  290.         if (*p && !nonzp)
  291.             nonzp = p;
  292.         } else if (c == '-') {
  293.         sawneg = 1;
  294.         } else if (c != ' ') {
  295.         /* advance to next component */
  296.         p = (p == d) ? m : s;
  297.         innum = 0;
  298.         }
  299.  
  300.     if (sawneg && nonzp)
  301.         *nonzp = -*nonzp;
  302. }
  303.  
  304. /* crack a floating date string, bp, of the form m/d/y, where d may be a
  305.  *   floating point number, into its components.
  306.  * leave any component unspecified unchanged.
  307.  * actually, the slashes may be anything but digits or a decimal point.
  308.  * this is functionally the same as f_sscansex() exept we allow for
  309.  *   the day portion to be real, and we don't handle negative numbers.
  310.  *   maybe someday we could make a combined one and use it everywhere.
  311.  */
  312. f_sscandate (bp, m, d, y)
  313. char *bp;
  314. int *m, *y;
  315. double *d;
  316. {
  317.     char *bp0, c;
  318.  
  319.     bp0 = bp;
  320.     while ((c = *bp++) && (c >= '0' && c <= '9'))
  321.         continue;
  322.     if (bp > bp0+1)
  323.         *m = atoi (bp0);
  324.     if (c == '\0')
  325.         return;
  326.     bp0 = bp;
  327.     while ((c = *bp++) && (c >= '0' && c <= '9' || c == '.'))
  328.         continue;
  329.     if (bp > bp0+1)
  330.         *d = atof (bp0);
  331.     if (c == '\0')
  332.         return;
  333.     bp0 = bp;
  334.     while (c = *bp++)
  335.         continue;
  336.     if (bp > bp0+1)
  337.         *y = atoi (bp0);
  338. }
  339.  
  340. /* just like dec_sex() but makes the first non-zero element negative if
  341.  * x is negative (instead of returning a sign flag).
  342.  */
  343. f_dec_sexsign (x, h, m, s)
  344. double x;
  345. int *h, *m, *s;
  346. {
  347.     int n;
  348.     dec_sex (x, h, m, s, &n);
  349.     if (n) {
  350.         if (*h)
  351.         *h = -*h;
  352.         else if (*m)
  353.         *m = -*m;
  354.         else
  355.         *s = -*s;
  356.     }
  357. }
  358.  
  359. /* return 1 if bp looks like a decimal year; else 0.
  360.  * any number greater than 12 or less than 0 is assumed to be a year, or any
  361.  * string with exactly one decimal point, an optional minus sign, and nothing
  362.  * else but digits.
  363.  */
  364. decimal_year (bp)
  365. char *bp;
  366. {
  367.     char c;
  368.     int ndig = 0, ndp = 0, nneg = 0, nchar = 0;
  369.     double y = atof(bp);
  370.  
  371.     while (c = *bp++) {
  372.         nchar++;
  373.         if (c >= '0' && c <= '9')
  374.         ndig++;
  375.         else if (c == '.')
  376.         ndp++;
  377.         else if (c == '-')
  378.         nneg++;
  379.     }
  380.  
  381.     return (y > 12 || y < 0
  382.             || (ndp == 1 && nneg <= 1 && nchar == ndig+ndp+nneg));
  383. }
  384.